Imports System.IO
Imports System.Xml
Module Subroutines

#Region "Variables"
    Public Words As New List(Of String)
    Public FavoritesFolder As String = My.Settings.BookmarkPath
    Public ErrorMessage As String
    Public RootNode As New TreeNode
    Public FindingDuplicates As Boolean
    Public AccessBookmarks As New IEbkm.Library
#End Region

#Region "Checking for Updates"
    Sub CheckForUpdates(ByVal OnlineUpdate As String, ByVal Silent As Boolean)
        Try
            Dim UpdateFile As String = My.Computer.FileSystem.SpecialDirectories.Temp & "\OpenBookmarksUpdateCheck.ini"
            My.Computer.Network.DownloadFile(OnlineUpdate, UpdateFile, Nothing, Nothing, False, 100000, True)
            Dim CurrentVersion As String = My.Application.Info.Version.ToString
            Dim NewVersion As String = SearchText("[LatestVersion]", UpdateFile)
            If CurrentVersion < NewVersion Then
                If MessageBox.Show("There is a new version of " & My.Application.Info.ProductName & " available. Would you like to download it?" & vbCrLf & "Current Version: " & CurrentVersion & vbCrLf & "New Version: " & NewVersion, "New version available", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
                    Dim UpdatedProgram As String = SearchText("[File]", UpdateFile)
                    My.Computer.Network.DownloadFile(UpdatedProgram, My.Computer.FileSystem.SpecialDirectories.Temp & "\OpenBookmarks-Update.exe", Nothing, Nothing, True, 100000, True)
                    System.Diagnostics.Process.Start(My.Computer.FileSystem.SpecialDirectories.Temp & "\OpenBookmarks-Update.exe")
                    End
                End If
            Else
                If Silent = False Then
                    MessageBox.Show("You are running the latest version of " & My.Application.Info.ProductName & ".", My.Application.Info.ProductName & " is up to date", MessageBoxButtons.OK, MessageBoxIcon.Information)
                End If
            End If
        Catch When Err.Number = 5
            My.Settings.CheckForUpdates = False
            ShowError("The updater cannot contact the update server. The program will now disable the automatic updater. You can enable it again in the options dialog", Err.ToString, Err.Number)
            'Application.Restart()
        Catch ex As Exception
            ShowError(ex.Message, ex.ToString, Err.Number)
        End Try
    End Sub


    Function SearchText(ByVal Wanted As String, ByVal TextFile As String) As String
        Dim line As String
        'Dim filename As String = Display.SelectedNode.Name
        Dim inputstream As StreamReader = File.OpenText(TextFile)
        line = inputstream.ReadLine()
        While line <> Nothing
            If line.IndexOf(Wanted) >= 0 Then
                line = inputstream.ReadLine()
                Exit While
            End If
            line = inputstream.ReadLine()
        End While
        inputstream.Close()
        Return line
    End Function
#End Region

#Region "Recent Bookmarks Menu"
    Sub SaveRecentSite(ByVal BookmarkFile As String)
        Dim filename As String = My.Application.Info.DirectoryPath & "\recent.txt"
        Dim CurrentText As String = File.ReadAllText(filename)
        Try
            FileOpen(1, filename, OpenMode.Output)
            PrintLine(1, BookmarkFile & vbCrLf & CurrentText)
            FileClose(1)
        Catch ex As Exception
            ErrorMessage = ex.ToString()
            If frmMain.icoTray.Visible = True Then
                frmMain.icoTray.ShowBalloonTip(10000, "An error has occured. Click here to save a log on your desktop", ex.Message, ToolTipIcon.Error)
            Else : frmMain.lblStatus.Text = "Error: " & Err.Description & " (click here to save error log to desktop)"
            End If
        End Try
    End Sub

    Sub AddToRecentMenu(ByVal RecentMenu As ToolStripMenuItem)
        Words.Clear()
        RecentMenu.DropDownItems.Clear()
        Try
            Dim line As String
            Dim filename As String = My.Application.Info.DirectoryPath & "\recent.txt"
            Dim i As Integer
            Dim inputstream As StreamReader = File.OpenText(filename)
            line = inputstream.ReadLine()
            While line <> Nothing And i < My.Settings.RecentBookmarksNumber
                Words.Add(line.ToString)
                line = inputstream.ReadLine
                i += 1
            End While
            inputstream.Close()
            LoadRecentMenu(RecentMenu)
        Catch ex As Exception
            'Do nothing. The error handling for opening a bookmark will do all the necessary work.
        End Try
    End Sub

    Sub LoadRecentMenu(ByVal RecentMenu As ToolStripMenuItem)
        'Load the menu from list of words.
        Dim SingleMenu As String
        For Each SingleMenu In Words
            Dim Menuname As String = SingleMenu
            SingleMenu = SingleMenu.Remove(0, Directory.GetParent(SingleMenu).ToString.Length + 1)
            SingleMenu = SingleMenu.Remove(SingleMenu.Length - 4, 4)
            RecentMenu.DropDownItems.Add(SingleMenu).Name = Menuname
        Next
    End Sub
#End Region

#Region "Load bookmarks"
    Sub LoadBookmarks(ByVal Display As TreeView)
        Try
            Dim xmlDoc As New XmlDocument()
            Dim tnNode As TreeNode
            Dim RootNode As New TreeNode
            RootNode.Text = "Bookmarks"
            RootNode.Name = FavoritesFolder
            xmlDoc.Load("Bookmarks.xml")
            display.Nodes.Clear()
            Display.Nodes.Add(RootNode)
            tnNode = New TreeNode
            tnNode = Display.TopNode
            AddNode(xmlDoc.DocumentElement, tnNode)
            LoadExpandedState(Display)
        Catch When Err.Number = 53
            Display.TopNode.Expand() 'This expands the root node when Expanded.xml can't be found
        Catch ex As Exception
            ShowError(ex.Message, ex.StackTrace.ToString, Err.Number)
        End Try
    End Sub

    Private Sub AddNode(ByVal inXmlNode As XmlNode, ByVal inTreeNode As TreeNode)
        Dim xNode As XmlNode
        Dim tNode As TreeNode
        Dim nodeList As XmlNodeList
        Dim i As Integer
        If inXmlNode.HasChildNodes Then
            nodeList = inXmlNode.ChildNodes
            i = 0
            While i <= nodeList.Count - 1
                xNode = inXmlNode.ChildNodes(i)
                Dim NewBookmark As New TreeNode
                If xNode.Name = "folder" Then
                    NewBookmark.ImageIndex = 1
                    NewBookmark.SelectedImageIndex = 1
                    NewBookmark.Name = xNode.Attributes(1).Value
                Else : NewBookmark.Name = xNode.Attributes(1).Value & "\" & xNode.Attributes(0).Value
                End If
                NewBookmark.Text = xNode.Attributes(0).Value
                inTreeNode.Nodes.Add(NewBookmark)
                tNode = inTreeNode.Nodes(i)
                i += 1
                AddNode(xNode, tNode)
            End While
        Else
            Dim BookmarkText As String = inXmlNode.Attributes(0).Value
            If BookmarkText.EndsWith("url") Then 'This makes sure that any empty folders won't get their names changed
                BookmarkText = BookmarkText.Remove(BookmarkText.Length - 4, 4)
            End If
            inTreeNode.Text = BookmarkText
        End If
    End Sub
#End Region

#Region "Remember Treeview Expanded State"
#Region "Save Treeview Expanded State"
    Dim DirectoryStructure As New XmlDocument
    Dim RootFolder As XmlElement

    Sub SaveExpandedState()
        Try
            DirectoryStructure.RemoveAll()
            DirectoryStructure.AppendChild(DirectoryStructure.CreateProcessingInstruction("xml", "version='1.0'"))
            MakeRootNode(frmMain.trvBookmarks.TopNode)
            DirectoryStructure.Save("Expanded.xml")
        Catch ex As Exception
            ShowError(ex.Message, ex.ToString, Err.Number.ToString)
        End Try
    End Sub

    Private Sub MakeRootNode(ByVal Node As TreeNode)
        Try
            RootFolder = DirectoryStructure.CreateElement("Bookmarks") 'Second Child: MyRoot
            RootFolder.SetAttribute("Expanded", Node.Tag)
            DirectoryStructure.AppendChild(RootFolder) 'Add the element to the xml document
            SaveState(RootFolder, frmMain.trvBookmarks.TopNode)
        Catch ex As Exception
            ShowError(ex.Message, ex.ToString, Err.Number.ToString)
        End Try
    End Sub

    Private Sub SaveState(ByVal XmlNode As XmlElement, ByVal treenode As TreeNode)
        Dim AllNodes As TreeNodeCollection = treenode.Nodes
        Dim node As TreeNode
        For Each node In AllNodes
            Dim oElmntChild As XmlElement
            oElmntChild = DirectoryStructure.CreateElement("bookmark")
            If node.Tag <> Nothing Then
                oElmntChild.SetAttribute("Expanded", node.Tag)
            Else : oElmntChild.SetAttribute("Expanded", "False")
            End If
            XmlNode.AppendChild(oElmntChild)
            SaveState(oElmntChild, node)
        Next
    End Sub
#End Region

#Region "Load Treeview Expanded State"
    Sub LoadExpandedState(ByVal Display As TreeView)
        Try
            Dim xmlDoc As New XmlDocument()
            Dim tnNode As TreeNode
            xmlDoc.Load("Expanded.xml")
            tnNode = New TreeNode
            tnNode = Display.TopNode
            RestoreNode(xmlDoc.DocumentElement, tnNode)
            Display.TopNode.Expand()
        Catch ex As Exception
            ShowError(ex.Message, ex.ToString, Err.Number)
        End Try
    End Sub

    Private Sub RestoreNode(ByVal inXmlNode As XmlNode, ByVal inTreeNode As TreeNode)
        Dim xNode As XmlNode
        Dim tNode As TreeNode
        Dim nodeList As XmlNodeList
        Dim i As Integer
        If inXmlNode.HasChildNodes Then
            nodeList = inXmlNode.ChildNodes
            i = 0
            While i <= nodeList.Count - 1
                xNode = inXmlNode.ChildNodes(i)
                If inXmlNode.Attributes(0).Value <> "False" Then
                    inTreeNode.Expand()
                Else : inTreeNode.Collapse()
                End If
                tNode = inTreeNode.Nodes(i)
                i += 1
                RestoreNode(xNode, tNode)
            End While
        End If
    End Sub
#End Region
#End Region

#Region "Error Handling"
    Sub LogError(ByVal e As String)
        Dim filename As String = My.Application.Info.DirectoryPath & "/" & My.Application.Info.ProductName & "ErrorLog.log"
        File.WriteAllText(filename, e)
    End Sub

    Sub ShowError(ByVal ErrorDescription As String, ByVal ErrorDetails As String, ByVal ErrorNumber As Integer)
        If frmMain.icoTray.Visible = True Then
            frmMain.icoTray.ShowBalloonTip(10000, "An error has occured (" & ErrorNumber & ")", ErrorDescription, ToolTipIcon.Error)
        Else : frmMain.lblStatus.Text = "Error: " & ErrorDescription
        End If
        LogError(ErrorDetails)
    End Sub
#End Region

    Sub LoadFoldersComboBox(ByVal ParentFolder As String, ByVal Display As ComboBox)
        Dim Folder As String
        Dim FolderArray() As String = Directory.GetDirectories(ParentFolder)
        For Each Folder In FolderArray
            Display.Items.Add(Folder.Remove(0, FavoritesFolder.Length))
            If Directory.GetDirectories(Folder) IsNot Nothing Then
                LoadFoldersComboBox(Folder, Display)
            End If
        Next
    End Sub

    Function CheckIfBookmark(ByVal Bookmark As String) As Boolean
        If Bookmark.EndsWith("url") And Bookmark <> frmMain.trvBookmarks.TopNode.Name Then
            Return True
        Else : Return False
        End If
    End Function

    Function GetHostName(ByVal Website As String) As String
        If Website.StartsWith("http://") Then
            Website = Website.Remove(0, 7)
        End If
        If Website.StartsWith("https://") Then
            Website = Website.Remove(0, 8)
        End If
        Dim Character As Char = "/"
        For Each Character In Website
            If Character = "/" Then
                Dim RemovalStart As Integer = Website.IndexOf(Character)
                Website = Website.Remove(RemovalStart, Website.Length - RemovalStart)
                Exit For
            End If
        Next
        Return Website
    End Function
End Module